package com.ys.service.finance.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.entity.finance.TcwAccountDetailedForCompany;
import com.ys.entity.finance.TcwRunningBack;
import com.ys.entity.finance.TcwRunningBackDetail;
import com.ys.entity.flow.YspModel;
import com.ys.entity.sys.TsRoleInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.TsUserInfo;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.TcwAccountDetailedForCompanyMapper;
import com.ys.mapper.finance.TcwRunningBackDetailMapper;
import com.ys.mapper.finance.TcwRunningBackMapper;
import com.ys.service.finance.TcwRunningBackService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.DateUtil;
import com.ys.util.RandomUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tcwRunningBackService")
public class TcwRunningBackImpl implements TcwRunningBackService {
	
	@Autowired
	private TcwRunningBackMapper tcwRunningBackMapper;
	@Autowired
	private TcwRunningBackDetailMapper tcwRunningBackDetailMapper;
	@Autowired
	private TcwAccountDetailedForCompanyMapper tcwAccountDetailedForCompanyMapper;
	@Autowired
	private YspTaskService yspTaskService;

	@Override
	public R checkForAdd(String ids) {
		
		
		// 验证账单详情是否存在已经返还过的
		if (new TcwRunningBackDetail().where("A.RunningIdOne in (" + ids + ")").count() > 0
				|| new TcwRunningBackDetail().where("A.RunningIdTwo in (" + ids + ")").count() > 0) {
			return R.error("存在已返还的数据，无法操作");
		}
		
		List<TcwAccountDetailedForCompany> listTcwAccountDetailedForCompany = new TcwAccountDetailedForCompany()
				.where("A.Id in (" + ids + ")")
				.setOrderby("A.Id asc")
				.queryList();
		
		// 流水ID列表，用于筛选重复选取的双向数据
		List<Long> listRunningId = new ArrayList<Long>();
		
		List<CheckForAddDto.RowDto> rows = new ArrayList<CheckForAddDto.RowDto>();
		for(TcwAccountDetailedForCompany tcwAccountDetailedForCompany1 : listTcwAccountDetailedForCompany) {
			
			if (listRunningId.contains(tcwAccountDetailedForCompany1.getId())) {
				continue;
			} else {
				listRunningId.add(tcwAccountDetailedForCompany1.getId());
			}

			// 根据创建时间范围，前后不能超过2秒
			Date createTime = tcwAccountDetailedForCompany1.getCreateTime();
			String createTimeMin = DateUtil.getYYYY_MM_DD_HH_mm_ss(DateUtil.addSecond(createTime, -1));
			String createTimeMax = DateUtil.getYYYY_MM_DD_HH_mm_ss(DateUtil.addSecond(createTime, 1));
			TcwAccountDetailedForCompany tcwAccountDetailedForCompany2 = new TcwAccountDetailedForCompany()
					.setVgsbmp(tcwAccountDetailedForCompany1.getVgsbm())
					.setVgsbm(tcwAccountDetailedForCompany1.getVgsbmp())
					.setFje(tcwAccountDetailedForCompany1.getFje().negate())
					.where("A.CreateTime BETWEEN '" + createTimeMin + "' and '" + createTimeMax + "'")
					.queryFirst();
			if (tcwAccountDetailedForCompany2 == null) {
				return R.error("流水ID【" + tcwAccountDetailedForCompany1.getId() + "】只有单向");
			}
			if (listRunningId.contains(tcwAccountDetailedForCompany2.getId())) {
				continue;
			} else {
				listRunningId.add(tcwAccountDetailedForCompany2.getId());
			}
			
			Long runningIdOne = tcwAccountDetailedForCompany1.getId();
			String vgsbmFromOne = tcwAccountDetailedForCompany1.getVgsbm();
			String vgsjcFromOne = tcwAccountDetailedForCompany1.getVgsjc();
			String vgsbmToOne = tcwAccountDetailedForCompany1.getVgsbmp();
			String vgsjcToOne = tcwAccountDetailedForCompany1.getVgsjcp();
			String vjylxOne = tcwAccountDetailedForCompany1.getVjylx();
			BigDecimal fjeOne = tcwAccountDetailedForCompany1.getFje();
			String vbzOne = tcwAccountDetailedForCompany1.getVbz();
			Long runningIdTwo = tcwAccountDetailedForCompany2.getId();
			String vgsbmFromTwo = tcwAccountDetailedForCompany2.getVgsbm();
			String vgsjcFromTwo = tcwAccountDetailedForCompany2.getVgsjc();
			String vgsbmToTwo = tcwAccountDetailedForCompany2.getVgsbmp();
			String vgsjcToTwo = tcwAccountDetailedForCompany2.getVgsjcp();
			String vjylxTwo = tcwAccountDetailedForCompany2.getVjylx();
			BigDecimal fjeTwo = tcwAccountDetailedForCompany2.getFje();
			String vbzTwo = tcwAccountDetailedForCompany2.getVbz();
			rows.add(new CheckForAddDto.RowDto(runningIdOne, vgsbmFromOne, vgsjcFromOne, vgsbmToOne, vgsjcToOne, vjylxOne, fjeOne, vbzOne, runningIdTwo, vgsbmFromTwo, vgsjcFromTwo, vgsbmToTwo, vgsjcToTwo, vjylxTwo, fjeTwo, vbzTwo));
		}
		
		CheckForAddDto dto = new CheckForAddDto(rows);
		return R.ok(dto);
	}
	
	@Override
	@Transactional
	public R add(String bid, String urlFile, String detailArr, Long menuId) throws Exception {
		
		// 验证订单号
		if (new TcwRunningBack().setBid(bid).count() > 0) {
			return R.error("该订单号已存在");
		}
		
		// 验证是否有详情数据
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}

		// 验证账单详情是否存在已经返还过的，同时验证数据是否重复
		String ids = "";
		List<Long> listId = new ArrayList<Long>();
		for (int i = 0; i < detailJA.size(); i++) {
			
			JSONObject detailJO = detailJA.getJSONObject(i);
			Long runningIdOne = detailJO.getLong("runningIdOne");
			Long runningIdTwo = detailJO.getLong("runningIdTwo");
			
			if (listId.contains(runningIdOne) || listId.contains(runningIdTwo)) {
				return R.error("存在重复的数据，无法操作");
			}
			listId.add(runningIdOne);
			listId.add(runningIdTwo);
			
			ids = ids + runningIdOne + "," + runningIdTwo + ",";
		}
		ids = ids.substring(0, ids.length() - 1);
		if (new TcwRunningBackDetail().where("A.RunningIdOne in (" + ids + ")").count() > 0) {
			return R.error("存在已返还的数据，无法操作");
		}
		
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
		
		// 添加费用返还单
		TcwRunningBack entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			entity = TcwRunningBack.tcwRunningBack(bid, effectStock, urlFile, createChangeId, 1);
		}
		tcwRunningBackMapper.insert(entity);
		
		// 添加费用返还单明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			Long runningIdOne = detailJO.getLong("runningIdOne");
			String vgsbmFromOne = detailJO.getString("vgsbmFromOne");
			String vgsjcFromOne = detailJO.getString("vgsjcFromOne");
			String vgsbmToOne = detailJO.getString("vgsbmToOne");
			String vgsjcToOne = detailJO.getString("vgsjcToOne");
			String vjylxOne = detailJO.getString("vjylxOne");
			BigDecimal fjeOne = detailJO.getBigDecimal("fjeOne");
			String vbzOne = detailJO.getString("vbzOne");
			Long runningIdTwo = detailJO.getLong("runningIdTwo");
			String vgsbmFromTwo = detailJO.getString("vgsbmFromTwo");
			String vgsjcFromTwo = detailJO.getString("vgsjcFromTwo");
			String vgsbmToTwo = detailJO.getString("vgsbmToTwo");
			String vgsjcToTwo = detailJO.getString("vgsjcToTwo");
			String vjylxTwo = detailJO.getString("vjylxTwo");
			BigDecimal fjeTwo = detailJO.getBigDecimal("fjeTwo");
			String vbzTwo = detailJO.getString("vbzTwo");
			TcwRunningBackDetail tcwRunningBackDetail = TcwRunningBackDetail.tcwRunningBackDetail(pbid, runningIdOne, vgsbmFromOne, vgsjcFromOne, vgsbmToOne, vgsjcToOne, vjylxOne, fjeOne, vbzOne,
					runningIdTwo, vgsbmFromTwo, vgsjcFromTwo, vgsbmToTwo, vgsjcToTwo, vjylxTwo, fjeTwo, vbzTwo, 1);
			tcwRunningBackDetailMapper.insert(tcwRunningBackDetail);
		}

		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		
		return R.ok(AddDto.gotoEdit("/web/finance/tcwRunningBack/toFlow?bid=" + entity.getBid()));
	}
	
	@Override
	@Transactional
	public R edit(Map<String, Object> params) throws Exception {
//		ThrOperateCompanyApply entity = JSON.parseObject(JSON.toJSONString(params), ThrOperateCompanyApply.class);
//		
//		// 验证编码
//		String vGsBm = entity.getVGsBm();
//		if (new ThrOperateCompanyApply().setVGsBm(vGsBm).where("A.Id != '" + params.get("id").toString() + "'").count() > 0) {
//			return R.error("公司编码【" + vGsBm + "】已存在");
//		}
//		
//		// 验证状态
//		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
//		if (ysProcInst == null) {
//			return R.error("审批数据不存在，无法编辑");
//		} else if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.INIT.value) {
//			return R.error("已流转，无法编辑");
//		}
//		
//		String vGsBmP = entity.getVGsBmP();
//		
//		// 若上级公司编码有改动，则节点值需一起变化
//		ThrOperateCompanyApply entityOld = new ThrOperateCompanyApply().setId(entity.getId()).queryFirst();
//		if (vGsBmP != null && vGsBmP.length() > 0 && !vGsBmP.equals(entityOld.getVGsBmP())) {
//			ThrOperateCompanyApply entityP = new ThrOperateCompanyApply().setId(entity.getPid()).queryFirst();
//
//			// 更新二叉树
//			Long nodeRgt = entityP.getNodeRgt();
//			hrMapper.updateThrOperateCompanyApplyNodeForInsertNode(nodeRgt, 2L);
//			
//			entity.setPid(entityP.getId());
//			entity.setFloor(entityP.getFloor() + 1);
//			entity.setNodeLft(nodeRgt);
//			entity.setNodeRgt(nodeRgt + 1);
//		}
//		
//		thrOperateCompanyApplyMapper.update(entity);
		return R.ok("操作成功");
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		TcwRunningBack entity = new TcwRunningBack().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		
		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		tcwRunningBackMapper.deleteTrue(id);
		
		// 删除子数据
		List<TcwRunningBackDetail> listTcwRunningBackDetail = new TcwRunningBackDetail().setPbid(entity.getBid()).queryList();
		for(TcwRunningBackDetail detail : listTcwRunningBackDetail) {
			tcwRunningBackDetailMapper.deleteTrue(detail.getId());
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(Long id, String loginUserId) throws Exception {
		
		TcwRunningBack entity = new TcwRunningBack().setId(id).queryFirst();
		String bid = entity.getBid();
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(id);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	@Transactional
	public void flowFinish(Long id) throws Exception {
		
		TcwRunningBack entity = new TcwRunningBack().setId(id).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		tcwRunningBackMapper.update(entity);
		
		// 操作人信息
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		TsUserInfo tsUserInfo = new TsUserInfo().setUserId(tsUserChange.getUserId()).queryFirst();
		TsRoleInfo tsRoleInfo = new TsRoleInfo().setGuid(tsUserInfo.getPositionGuid()).queryFirst();
		
		Date now = new Date();
		List<TcwRunningBackDetail> listTcwRunningBackDetail = new TcwRunningBackDetail().setPbid(entity.getBid()).queryList();
		for(TcwRunningBackDetail tcwRunningBackDetail : listTcwRunningBackDetail) {
			// 添加第一条流水
			{
				TcwAccountDetailedForCompany tcwAccountDetailedForCompanyOld = new TcwAccountDetailedForCompany().setId(tcwRunningBackDetail.getRunningIdOne()).queryFirst();
				String guid = RandomUtil.getGUID();
				String vGsBm = tcwAccountDetailedForCompanyOld.getVgsbm();
				String vGsJc = tcwAccountDetailedForCompanyOld.getVgsjc();
				String vGsBmP = tcwAccountDetailedForCompanyOld.getVgsbmp();
				String vGsJcP = tcwAccountDetailedForCompanyOld.getVgsjcp();
				String vJyLx = tcwAccountDetailedForCompanyOld.getVjylx();
				BigDecimal fJe = tcwAccountDetailedForCompanyOld.getFje().negate();
				BigDecimal fjeLeft = null; // TODO
				Date dJySj = now;
				Date dShSj = now;
				String vBz = "（退回）费用返还单：单号" + entity.getBid() + "，原备注：" + tcwAccountDetailedForCompanyOld.getVbz();
				String mName = tcwAccountDetailedForCompanyOld.getMname();
				Integer mType = tcwAccountDetailedForCompanyOld.getMtype();
				String mNid = null;
				String mBid = null;
				String mGuid = null;
				Date writeTime = now;
				String operatorDept = tsUserChange.getDeptName();
				String operatorPosition = tsRoleInfo != null ? tsRoleInfo.getRoleName() : null;
				String operatorName = tsUserChange.getUserName();
				String operatorUserId = tsUserChange.getUserId();
				String vzhlx = tcwAccountDetailedForCompanyOld.getVzhlx();
				TcwAccountDetailedForCompany tcwAccountDetailedForCompanyNew = TcwAccountDetailedForCompany.tcwAccountDetailedForCompany(
						guid, vGsBm, vGsJc, vGsBmP, vGsJcP, vJyLx, fJe, fjeLeft, dJySj, dShSj, vBz, mName, mType, mNid, mBid, mGuid, writeTime, operatorDept, operatorPosition, operatorName, operatorUserId, vzhlx, 1);
				tcwAccountDetailedForCompanyMapper.insert(tcwAccountDetailedForCompanyNew);
			}
			
			// 添加第二条流水
			{
				TcwAccountDetailedForCompany tcwAccountDetailedForCompanyOld = new TcwAccountDetailedForCompany().setId(tcwRunningBackDetail.getRunningIdTwo()).queryFirst();
				String guid = RandomUtil.getGUID();
				String vGsBm = tcwAccountDetailedForCompanyOld.getVgsbm();
				String vGsJc = tcwAccountDetailedForCompanyOld.getVgsjc();
				String vGsBmP = tcwAccountDetailedForCompanyOld.getVgsbmp();
				String vGsJcP = tcwAccountDetailedForCompanyOld.getVgsjcp();
				String vJyLx = tcwAccountDetailedForCompanyOld.getVjylx();
				BigDecimal fJe = tcwAccountDetailedForCompanyOld.getFje().negate();
				BigDecimal fjeLeft = null; // TODO
				Date dJySj = now;
				Date dShSj = now;
				String vBz = "（退回）费用返还单：单号" + entity.getBid() + "，原备注：" + tcwAccountDetailedForCompanyOld.getVbz();
				String mName = tcwAccountDetailedForCompanyOld.getMname();
				Integer mType = tcwAccountDetailedForCompanyOld.getMtype();
				String mNid = null;
				String mBid = null;
				String mGuid = null;
				Date writeTime = now;
				String operatorDept = tsUserChange.getDeptName();
				String operatorPosition = tsRoleInfo != null ? tsRoleInfo.getRoleName() : null;
				String operatorName = tsUserChange.getUserName();
				String operatorUserId = tsUserChange.getUserId();
				String vzhlx = tcwAccountDetailedForCompanyOld.getVzhlx();
				TcwAccountDetailedForCompany tcwAccountDetailedForCompanyNew = TcwAccountDetailedForCompany.tcwAccountDetailedForCompany(
						guid, vGsBm, vGsJc, vGsBmP, vGsJcP, vJyLx, fJe, fjeLeft, dJySj, dShSj, vBz, mName, mType, mNid, mBid, mGuid, writeTime, operatorDept, operatorPosition, operatorName, operatorUserId, vzhlx, 1);
				tcwAccountDetailedForCompanyMapper.insert(tcwAccountDetailedForCompanyNew);
			}
		}
	}

	@Override
	public String getBidForAdd() {
		Date now = new Date();
		String today = DateUtil.getYYYY_MM_DD(now);
		String pre = "FYFH";
		String mid = today.replace("-", "").substring(2);
		Integer numToday = new TcwRunningBack().where("A.CreateTime between '" + today + " 00:00:00' and '" + today + " 23:59:59'").count();
		String last = "" + (1000 + numToday + 1);
		
		return pre + "-" + mid + "-" + last;
	}
}
